import { Injectable, Logger } from "@nestjs/common";
import { InjectRepository } from "@nestjs/typeorm";
import { Repository, MoreThan, DataSource, In } from "typeorm";
import { GemBaseEntity } from "../entities/gem-base.entity";
import { CharacterGemInventoryEntity } from "../entities/character-gem-inventory.entity";
import { EquipmentGemSocketEntity } from "../entities/equipment-gem-socket.entity";
import { GemMiningEntity } from "../entities/gem-mining.entity";
import { CharacterInventoryEntity } from "../entities/character-inventory.entity";
import { CharacterEquipmentInventoryEntity } from "../entities/character-equipment-inventory.entity";
import { CharacterMineralEntity } from "../entities/character-mineral.entity";
import { GemAttributeEntity } from "../entities/gem-attribute.entity";
import { CharacterResourcesEntity } from "../entities/character-resources.entity";

@Injectable()
export class GemService {
  private readonly logger = new Logger(GemService.name);

  constructor(
    @InjectRepository(GemBaseEntity)
    private gemBaseRepository: Repository<GemBaseEntity>,
    @InjectRepository(CharacterGemInventoryEntity)
    private gemInventoryRepository: Repository<CharacterGemInventoryEntity>,
    @InjectRepository(EquipmentGemSocketEntity)
    private gemSocketRepository: Repository<EquipmentGemSocketEntity>,
    @InjectRepository(GemMiningEntity)
    private gemMiningRepository: Repository<GemMiningEntity>,
    @InjectRepository(CharacterInventoryEntity)
    private characterInventoryRepository: Repository<CharacterInventoryEntity>,
    @InjectRepository(CharacterEquipmentInventoryEntity)
    private characterEquipmentInventoryRepository: Repository<CharacterEquipmentInventoryEntity>,
    @InjectRepository(GemAttributeEntity)
    private gemAttributeRepository: Repository<GemAttributeEntity>,
    @InjectRepository(CharacterResourcesEntity)
    private characterResourcesRepository: Repository<CharacterResourcesEntity>,
    private readonly dataSource: DataSource
  ) {}

  /**
   * 查询角色宝石背包 (6034)
   */
  async getCharacterGems(
    characterId: number,
    pageNum: number = 0,
    pageSize: number = 20
  ) {
    try {
      const [gems, total] = await this.gemInventoryRepository.findAndCount({
        where: {
          characterId,
          status: 1,
        },
        skip: pageNum * pageSize,
        take: pageSize,
        // 根据宝石等级降序排序，再按获得时间降序，确保分页前已排序
        order: { level: "DESC", obtainedAt: "DESC" },
        relations: ["gemBase"],
      });

      // 按照标准指令说明文档的格式返回数据
      const list = gems.map((gem: any) => ({
        id: gem.id,
        lvl: gem.level,
        name: gem.name,
        num: 1, // 宝石不能叠加，数量固定为1
        type: gem.gemBase?.type || 1,
      }));

      return {
        list,
        total,
        page: pageNum + 1,
        sum: total,
      };
    } catch (error) {
      console.error("查询角色宝石背包失败:", error);
      throw error;
    }
  }

  /**
   * VIP奖励：直接生成指定等级的随机宝石（无任何消耗）
   */
  async awardRandomGems(
    characterId: number,
    level: number,
    count: number = 1
  ): Promise<Array<{ id: number; name: string; level: number }>> {
    const queryRunner = this.dataSource.createQueryRunner();
    await queryRunner.connect();
    await queryRunner.startTransaction();

    try {
      // 随机可选宝石类型集合：取所有启用的 gem_base
      const allGemBases = await queryRunner.manager.find(GemBaseEntity, {
        where: {},
      });
      if (!allGemBases || allGemBases.length === 0) {
        await queryRunner.rollbackTransaction();
        return [];
      }

      const results: Array<{ id: number; name: string; level: number }> = [];

      for (let i = 0; i < Math.max(1, count); i++) {
        const base =
          allGemBases[Math.floor(Math.random() * allGemBases.length)];

        // 可能属性
        const possibleAttributes = await this.getGemPossibleAttributes(base.id);
        if (!possibleAttributes || possibleAttributes.length === 0) {
          continue;
        }

        // 按权重选择属性
        const selectedAttribute =
          this.selectAttributeByWeight(possibleAttributes);

        // 生成属性值
        let finalLevel = Math.max(1, Math.min(10, Math.floor(level)));
        let attributeValue: number;
        if (selectedAttribute.type === 31) {
          // 连击数属性限定8-10级
          if (finalLevel < 8) finalLevel = 8;
          if (finalLevel > 10) finalLevel = 10;
          attributeValue = Math.floor(Math.random() * 3) + 1; // 1-3
        } else {
          attributeValue = this.computeAttributeValue(
            finalLevel,
            selectedAttribute.max
          );
        }

        // 入库
        const nameWithLevel = `${base.name}(等级${finalLevel})`;
        const row = await queryRunner.manager.insert(
          CharacterGemInventoryEntity,
          {
            characterId,
            gemBaseId: base.id,
            name: nameWithLevel,
            level: finalLevel,
            attributeType: selectedAttribute.type,
            attributeValue,
            status: 1,
            obtainedAt: new Date(),
            created_at: new Date(),
            updated_at: new Date(),
          }
        );

        results.push({
          id: (row.identifiers?.[0]?.id as number) || 0,
          name: nameWithLevel,
          level: finalLevel,
        });
      }

      await queryRunner.commitTransaction();
      return results;
    } catch (error) {
      await queryRunner.rollbackTransaction();
      this.logger.error("VIP发放宝石失败:", error);
      throw error;
    } finally {
      await queryRunner.release();
    }
  }

  /**
   * 以与开矿(2032)一致的“属性风格”生成并发放1颗随机宝石
   * 名称形如：宝石名(属性名 属性值)，并正确处理连击数(8-10级限制)
   */
  async awardRandomAttributeGem(
    characterId: number,
    level: number
  ): Promise<{ id: number; name: string; level: number } | null> {
    const queryRunner = this.dataSource.createQueryRunner();
    await queryRunner.connect();
    await queryRunner.startTransaction();
    try {
      // 选取任意启用的宝石基础（与 awardRandomGems 策略保持一致）
      const allGemBases = await queryRunner.manager.find(GemBaseEntity, {
        where: {},
      });
      if (!allGemBases || allGemBases.length === 0) {
        await queryRunner.rollbackTransaction();
        return null;
      }

      const base = allGemBases[Math.floor(Math.random() * allGemBases.length)];
      const possibleAttributes = await this.getGemPossibleAttributes(base.id);
      if (!possibleAttributes || possibleAttributes.length === 0) {
        await queryRunner.rollbackTransaction();
        return null;
      }

      const selectedAttribute =
        this.selectAttributeByWeight(possibleAttributes);

      // 处理等级与属性值（连击数属性限定 8-10 级）
      let finalLevel = Math.max(1, Math.min(10, Math.floor(level)));
      let attributeValue: number;
      if (selectedAttribute.type === 31) {
        if (finalLevel < 8) finalLevel = 8;
        if (finalLevel > 10) finalLevel = 10;
        attributeValue = Math.floor(Math.random() * 3) + 1; // 1-3
      } else {
        attributeValue = this.computeAttributeValue(
          finalLevel,
          selectedAttribute.max
        );
      }

      const nameWithAttr = `${base.name}(${selectedAttribute.name} ${attributeValue})`;

      const row = await queryRunner.manager.insert(
        CharacterGemInventoryEntity,
        {
          characterId,
          gemBaseId: base.id,
          name: nameWithAttr,
          level: finalLevel,
          attributeType: selectedAttribute.type,
          attributeValue,
          status: 1,
          obtainedAt: new Date(),
          created_at: new Date(),
          updated_at: new Date(),
        }
      );

      await queryRunner.commitTransaction();
      return {
        id: (row.identifiers?.[0]?.id as number) || 0,
        name: nameWithAttr,
        level: finalLevel,
      };
    } catch (error) {
      await queryRunner.rollbackTransaction();
      this.logger.error("属性风格发放宝石失败:", error);
      throw error;
    } finally {
      await queryRunner.release();
    }
  }
  /**
   * 开矿生成宝石
   */
  async mineGems(
    characterId: number,
    miningType: number,
    keyItemId: number,
    boxItemId: number
  ): Promise<{ success: boolean; message: string; gems?: any[] }> {
    const queryRunner = this.dataSource.createQueryRunner();
    await queryRunner.connect();
    await queryRunner.startTransaction();

    try {
      // 获取开矿配置
      const miningConfig = await queryRunner.manager.findOne(GemMiningEntity, {
        where: { type: miningType, status: 1 },
      });

      if (!miningConfig) {
        await queryRunner.rollbackTransaction();
        return {
          success: false,
          message: "矿洞配置不存在",
        };
      }

      // 检查钥匙是否匹配
      if (miningConfig.keyItemId !== keyItemId) {
        await queryRunner.rollbackTransaction();
        return {
          success: false,
          message: `开${miningConfig.name}需要${miningConfig.keyItemName}`,
        };
      }

      // 检查玩家是否有足够的钥匙
      const keyItem = await queryRunner.manager.findOne(
        CharacterInventoryEntity,
        {
          where: {
            characterId,
            itemId: keyItemId,
            status: 1,
            num: MoreThan(0),
          },
        }
      );

      if (!keyItem || keyItem.num < 1) {
        await queryRunner.rollbackTransaction();
        return {
          success: false,
          message: `开${miningConfig.name}需要${miningConfig.keyItemName}，您可以在[功能]项的[宝库]中购买`,
        };
      }

      // 检查玩家是否有对应的宝盒（矿石背包）
      const boxItem = await queryRunner.manager.findOne(
        CharacterMineralEntity,
        {
          where: {
            characterId,
            itemId: boxItemId,
            status: 1,
            num: MoreThan(0),
          },
        }
      );

      if (!boxItem || boxItem.num < 1) {
        await queryRunner.rollbackTransaction();
        return {
          success: false,
          message: `开矿需要对应的宝盒，请检查背包中是否有宝盒`,
        };
      }

      // 消耗钥匙
      await queryRunner.manager.update(
        CharacterInventoryEntity,
        { id: keyItem.id },
        { num: keyItem.num - 1, updated_at: new Date() }
      );

      // 消耗宝盒（从矿石背包扣减）
      const nextBoxNum = (boxItem.num || 0) - 1;
      await queryRunner.manager.update(
        CharacterMineralEntity,
        { id: boxItem.id },
        nextBoxNum > 0
          ? { num: nextBoxNum, updated_at: new Date() }
          : { num: 0, status: 0, updated_at: new Date() }
      );

      // 解析宝石类型
      let gemTypes: number[] = [];
      try {
        gemTypes = miningConfig.gemTypes
          ? JSON.parse(miningConfig.gemTypes)
          : [];
      } catch (error) {
        this.logger.error("解析宝石类型失败:", error);
        gemTypes = [];
      }

      // 生成宝石
      const gems = await this.generateGemsWithTransaction(
        queryRunner,
        characterId,
        miningConfig.minLevel,
        miningConfig.maxLevel,
        gemTypes
      );

      await queryRunner.commitTransaction();

      return {
        success: true,
        message: `成功开启${miningConfig.name}，获得${gems.length}个宝石`,
        gems,
      };
    } catch (error) {
      await queryRunner.rollbackTransaction();
      console.error("开矿失败:", error);
      throw error;
    } finally {
      await queryRunner.release();
    }
  }

  /**
   * 生成宝石 (带事务) - 新版本支持多种属性随机选择
   */
  private async generateGemsWithTransaction(
    queryRunner: any,
    characterId: number,
    minLevel: number,
    maxLevel: number,
    gemTypes: number[]
  ): Promise<any[]> {
    const gems = [];

    // 随机生成1-3个宝石
    const gemCount = Math.floor(Math.random() * 3) + 1;

    for (let i = 0; i < gemCount; i++) {
      // 随机选择宝石类型
      const randomTypeIndex = Math.floor(Math.random() * gemTypes.length);
      const gemType = gemTypes[randomTypeIndex];

      // 获取宝石基础信息
      const gemBase = await queryRunner.manager.findOne(GemBaseEntity, {
        where: { id: gemType },
      });

      if (!gemBase) {
        console.warn(`宝石基础信息不存在: gemType=${gemType}`);
        continue;
      }

      // 获取宝石的可能属性
      const possibleAttributes = await this.getGemPossibleAttributes(gemType);
      if (possibleAttributes.length === 0) {
        console.warn(`宝石没有可能的属性: gemType=${gemType}`);
        continue;
      }

      // 随机生成等级
      const level =
        Math.floor(Math.random() * (maxLevel - minLevel + 1)) + minLevel;

      // 根据权重选择属性
      const selectedAttribute =
        this.selectAttributeByWeight(possibleAttributes);

      // 特殊属性处理
      let finalLevel = level;
      let attributeValue: number;

      if (selectedAttribute.type === 31) {
        // 连击数只支持8-10级宝石
        if (level < 8) {
          finalLevel = 8;
        } else if (level > 10) {
          finalLevel = 10;
        }
        // 连击数值为1-3
        attributeValue = Math.floor(Math.random() * 3) + 1; // 1-3
      } else {
        // 使用新规则：(等级 + 随机0-2) * (max_value / 15)
        attributeValue = this.computeAttributeValue(
          level,
          selectedAttribute.max
        );
      }

      // 生成宝石名称：宝石名(属性名称 属性值)
      const gemName = `${gemBase.name}(${selectedAttribute.name} ${attributeValue})`;

      // 保存到数据库
      const gemInventory = await queryRunner.manager.save(
        CharacterGemInventoryEntity,
        {
          characterId,
          gemBaseId: gemBase.id,
          name: gemName,
          level: finalLevel,
          attributeType: selectedAttribute.type, // 使用属性类型
          attributeValue,
          status: 1,
          obtainedAt: new Date(),
        }
      );

      gems.push({
        id: gemInventory.id,
        name: gemName,
        level: finalLevel,
        type: gemType,
        attributeType: selectedAttribute.type,
        attributeValue,
      });
    }

    return gems;
  }

  /**
   * 为角色发放一颗随机宝石（指定等级，随机基础与随机属性）
   * 参数仅需要等级，供开矿与VIP领取复用
   */
  async awardRandomGemWithLevel(
    queryRunner: any,
    characterId: number,
    level: number
  ): Promise<{
    id: number;
    name: string;
    level: number;
    base_id: number;
    attributeType: number;
    attributeValue: number;
  }> {
    // 随机挑选有可用属性的宝石基础
    const bases: GemBaseEntity[] = await queryRunner.manager.find(
      GemBaseEntity,
      { where: {} }
    );
    if (!bases || bases.length === 0) {
      throw new Error("宝石基础数据不存在");
    }

    let gemBase: GemBaseEntity | null = null;
    let possibleAttributes: any[] = [];
    for (let i = 0; i < 5; i++) {
      const pick = bases[Math.floor(Math.random() * bases.length)];
      const attrs = await this.getGemPossibleAttributes((pick as any).id);
      if (attrs && attrs.length > 0) {
        gemBase = pick;
        possibleAttributes = attrs;
        break;
      }
    }
    if (!gemBase || possibleAttributes.length === 0) {
      throw new Error("宝石属性配置缺失");
    }

    // 选属性 + 计算属性值
    const selectedAttribute = this.selectAttributeByWeight(possibleAttributes);
    let finalLevel = Math.max(1, Math.min(10, Math.floor(level)));
    let attributeValue: number;
    if (selectedAttribute.type === 31) {
      if (finalLevel < 8) finalLevel = 8;
      if (finalLevel > 10) finalLevel = 10;
      attributeValue = Math.floor(Math.random() * 3) + 1;
    } else {
      attributeValue = this.computeAttributeValue(
        finalLevel,
        selectedAttribute.max
      );
    }

    const gemName = `${gemBase.name}(${selectedAttribute.name} ${attributeValue})`;
    const gemInventory = await queryRunner.manager.save(
      CharacterGemInventoryEntity,
      {
        characterId,
        gemBaseId: (gemBase as any).id,
        name: gemName,
        level: finalLevel,
        attributeType: selectedAttribute.type,
        attributeValue,
        status: 1,
        obtainedAt: new Date(),
      }
    );

    return {
      id: (gemInventory as any).id,
      name: gemName,
      level: finalLevel,
      base_id: (gemBase as any).id,
      attributeType: selectedAttribute.type,
      attributeValue,
    };
  }

  /**
   * 查询可用于合成的同级宝石列表（1284）
   */
  async listCombinableGems(
    characterId: number,
    level: number,
    pageNum: number = 0,
    pageSize: number = 40
  ): Promise<{ list: any[]; page: number; sum: number }> {
    const qb = this.gemInventoryRepository
      .createQueryBuilder("g")
      .leftJoinAndSelect("g.gemBase", "base")
      .where("g.character_id = :cid", { cid: characterId })
      .andWhere("g.status = 1")
      .andWhere("g.level = :lv", { lv: level })
      .orderBy("g.id", "ASC")
      .skip(pageNum * pageSize)
      .take(pageSize);
    const [rows, total] = await qb.getManyAndCount();

    // 将 attributeType 映射到 gem_attributes.short_name
    const attributeTypeIds = Array.from(
      new Set(
        rows
          .map((r: any) => r.attributeType)
          .filter((id: number | null | undefined) => typeof id === "number")
      )
    ) as number[];

    const shortNameMap: Record<number, string> = {};
    if (attributeTypeIds.length > 0) {
      const attrs = await this.gemAttributeRepository.find({
        where: { id: In(attributeTypeIds) },
        select: ["id", "shortName"],
      });
      for (const a of attrs) {
        shortNameMap[a.id] = a.shortName || "";
      }
    }

    const list = rows.map((r: any) => ({
      i: r.gemBaseId,
      id: r.id,
      lvl: r.level,
      n: r.gemBase?.name || r.name,
      t: r.attributeType ? shortNameMap[r.attributeType] || "" : "",
      v: r.attributeValue || 0,
    }));
    return { list, page: pageNum, sum: total };
  }

  /**
   * 合成两颗同级宝石为更高一级（消耗两颗，生成1颗随机属性的新宝石）（1286）
   */
  async combineTwoGems(
    characterId: number,
    id1: number,
    id2: number
  ): Promise<{ newGem: any; level: number; baseName: string }> {
    const queryRunner = this.dataSource.createQueryRunner();
    await queryRunner.connect();
    await queryRunner.startTransaction();
    try {
      const g1 = await queryRunner.manager.findOne(
        CharacterGemInventoryEntity,
        { where: { id: id1, characterId } }
      );
      const g2 = await queryRunner.manager.findOne(
        CharacterGemInventoryEntity,
        { where: { id: id2, characterId } }
      );
      if (!g1 || !g2) {
        throw new Error("宝石不存在或不属于当前玩家");
      }
      if (g1.status !== 1 || g2.status !== 1) {
        throw new Error("宝石状态不可用");
      }
      if (g1.level !== g2.level) {
        throw new Error("两颗宝石等级必须相同");
      }
      if (g1.level >= 10) {
        throw new Error("已达最高等级，无法继续合成");
      }

      // 计算合成后等级与银币消耗：新等级 * 100 银
      const newLevel = (g1.level || 1) + 1;
      const costSilver = newLevel * 100;
      const resRow = await queryRunner.manager.findOne(
        CharacterResourcesEntity,
        { where: { characterId } }
      );
      const currentSilver = Number((resRow as any)?.silver || 0);
      if (!resRow || currentSilver < costSilver) {
        throw new Error(`银两不足，合成需要${costSilver}银两`);
      }
      await queryRunner.manager.update(
        CharacterResourcesEntity,
        { characterId },
        { silver: currentSilver - costSilver }
      );

      // 消耗两颗（置为已使用）
      await queryRunner.manager.update(
        CharacterGemInventoryEntity,
        { id: (g1 as any).id },
        { status: 0, updated_at: new Date() }
      );
      await queryRunner.manager.update(
        CharacterGemInventoryEntity,
        { id: (g2 as any).id },
        { status: 0, updated_at: new Date() }
      );

      // 生成新宝石：等级+1
      const newGem = await this.awardRandomGemWithLevel(
        queryRunner,
        characterId,
        newLevel
      );

      // 查询基础名
      const base = await queryRunner.manager.findOne(GemBaseEntity, {
        where: { id: (newGem as any).base_id },
      });
      const baseName = base?.name || "宝石";

      await queryRunner.commitTransaction();
      return { newGem, level: newLevel, baseName };
    } catch (e) {
      await queryRunner.rollbackTransaction();
      throw e;
    } finally {
      await queryRunner.release();
    }
  }

  /**
   * 根据宝石ID查询可以镶嵌的装备 (1090)
   */
  async getSocketableEquipment(
    characterId: number,
    gemInventoryId: number
  ): Promise<{ success: boolean; message: string; data?: any[] }> {
    try {
      // 检查宝石是否存在且属于该角色
      const gemInventory = await this.gemInventoryRepository.findOne({
        where: { id: gemInventoryId, characterId, status: 1 },
        relations: ["gemBase"],
      });

      if (!gemInventory) {
        return { success: false, message: "宝石不存在或已被使用" };
      }

      // 获取宝石的实际属性类型
      const actualAttributeType = gemInventory.attributeType;

      if (!actualAttributeType) {
        return { success: false, message: "该宝石没有属性信息" };
      }

      // 从gem_attributes表获取实际属性的装备槽位
      const gemAttributeResults = await this.dataSource.query(
        `SELECT equipment_slots FROM gem_attributes WHERE id = ?`,
        [actualAttributeType]
      );

      if (gemAttributeResults.length === 0) {
        return { success: false, message: "该宝石不能镶嵌到任何装备上" };
      }

      const gemAttribute = gemAttributeResults[0];
      const equipmentSlots = gemAttribute.equipment_slots;

      if (!equipmentSlots || equipmentSlots.length === 0) {
        return { success: false, message: "该宝石不能镶嵌到任何装备上" };
      }

      // 解析装备槽位字符串为数组
      const equipmentTypes = equipmentSlots
        .split(",")
        .map((slot: string) => parseInt(slot.trim()));

      const equipments = await this.characterEquipmentInventoryRepository
        .createQueryBuilder("equipment")
        .leftJoin("equipment.equipmentBase", "base")
        .where("equipment.characterId = :characterId", { characterId })
        .andWhere("equipment.status = 1")
        .andWhere("base.type IN (:...types)", { types: equipmentTypes })
        .select([
          "equipment.id",
          "equipment.name",
          "base.type",
          "equipment.equipmentId",
        ])
        .getMany();

      // 为每个装备添加宝石槽位信息
      const result = equipments.map((equipment) => {
        const baseType = equipment.equipmentBase?.type;

        // 查询已镶嵌的宝石，直接使用数字类型
        return this.getEquipmentSocketInfo(characterId, equipment.id, baseType);
      });

      const equipmentList = await Promise.all(result);

      // 过滤掉槽位已满的装备（stoneStr中没有"空"字）
      const availableEquipments = equipmentList.filter((equipment) => {
        return equipment.stoneStr && equipment.stoneStr.includes("空");
      });

      return {
        success: true,
        message: "查询成功",
        data: availableEquipments,
      };
    } catch (error) {
      console.error("查询可镶嵌装备失败:", error);
      throw error;
    }
  }

  /**
   * 获取装备的宝石槽位信息
   */
  private async getEquipmentSocketInfo(
    characterId: number,
    equipmentId: number,
    equipmentType: number
  ): Promise<any> {
    // 查询装备信息
    const equipment = await this.characterEquipmentInventoryRepository.findOne({
      where: { id: equipmentId, characterId },
      relations: ["equipmentBase"],
    });

    if (!equipment) {
      return {
        id: equipmentId,
        name: "未知装备",
        stoneStr: "(空,空,空)",
      };
    }

    // 查询已镶嵌的宝石
    const sockets = await this.gemSocketRepository.find({
      where: { characterId, equipmentId, equipmentType },
      order: { socketSlot: "ASC" },
    });

    // 构建宝石槽位字符串
    const stoneStr = [];
    for (let i = 1; i <= 3; i++) {
      const socket = sockets.find((s) => s.socketSlot === i);
      stoneStr.push(socket ? socket.gemName : "空");
    }

    return {
      id: equipmentId,
      name: equipment.name || equipment.equipmentBase?.name || "未知装备",
      stoneStr: `(${stoneStr.join(",")})`,
    };
  }

  /**
   * 镶嵌宝石到装备 (1092)
   */
  async socketGemToEquipment(
    characterId: number,
    gemInventoryId: number,
    equipmentId: number
  ): Promise<{ success: boolean; message: string }> {
    const queryRunner = this.dataSource.createQueryRunner();
    await queryRunner.connect();
    await queryRunner.startTransaction();

    try {
      // 检查宝石是否存在且属于该角色
      const gemInventory = await queryRunner.manager.findOne(
        CharacterGemInventoryEntity,
        {
          where: { id: gemInventoryId, characterId, status: 1 },
          relations: ["gemBase"],
        }
      );

      if (!gemInventory) {
        await queryRunner.rollbackTransaction();
        return { success: false, message: "宝石不存在或已被使用" };
      }

      if (!gemInventory.gemBase) {
        await queryRunner.rollbackTransaction();
        return { success: false, message: "宝石基础信息不存在" };
      }

      // 检查装备是否存在且属于该角色
      const equipment = await queryRunner.manager.findOne(
        CharacterEquipmentInventoryEntity,
        {
          where: { id: equipmentId, characterId, status: 1 },
          relations: ["equipmentBase"],
        }
      );

      if (!equipment) {
        await queryRunner.rollbackTransaction();
        return { success: false, message: "装备不存在或已被使用" };
      }

      // 获取装备类型（数字）
      const equipmentType = equipment.equipmentBase?.type;
      if (!equipmentType) {
        await queryRunner.rollbackTransaction();
        return { success: false, message: "未知的装备类型" };
      }

      // 检查宝石是否可以镶嵌到该装备类型
      const actualAttributeType = gemInventory.attributeType;

      if (!actualAttributeType) {
        await queryRunner.rollbackTransaction();
        return { success: false, message: "该宝石没有属性信息" };
      }

      // 从gem_attributes表获取实际属性的装备槽位
      const gemAttributeResults = await queryRunner.query(
        `SELECT equipment_slots FROM gem_attributes WHERE id = ?`,
        [actualAttributeType]
      );

      if (gemAttributeResults.length === 0) {
        await queryRunner.rollbackTransaction();
        return { success: false, message: "该宝石不能镶嵌到任何装备上" };
      }

      const gemAttribute = gemAttributeResults[0];
      const equipmentSlots = gemAttribute.equipment_slots;

      if (!equipmentSlots || equipmentSlots.length === 0) {
        await queryRunner.rollbackTransaction();
        return { success: false, message: "该宝石不能镶嵌到任何装备上" };
      }

      // 解析装备槽位字符串为数组
      const equipmentTypes = equipmentSlots
        .split(",")
        .map((slot: string) => parseInt(slot.trim()));

      if (!equipmentTypes.includes(equipmentType)) {
        await queryRunner.rollbackTransaction();
        return {
          success: false,
          message: `该宝石不能镶嵌到${
            equipment.equipmentBase?.name || equipment.name || "未知装备"
          }上`,
        };
      }

      // 查找可用的宝石槽位
      const existingSockets = await queryRunner.manager.find(
        EquipmentGemSocketEntity,
        {
          where: { characterId, equipmentId, equipmentType },
        }
      );

      if (existingSockets.length >= 3) {
        await queryRunner.rollbackTransaction();
        return { success: false, message: "该装备的宝石槽位已满" };
      }

      // 找到第一个可用的槽位
      const usedSlots = existingSockets.map((s) => s.socketSlot);
      let availableSlot = 1;
      while (usedSlots.includes(availableSlot)) {
        availableSlot++;
      }

      // 创建镶嵌记录
      await queryRunner.manager.save(EquipmentGemSocketEntity, {
        characterId,
        equipmentId,
        equipmentType,
        socketSlot: availableSlot,
        gemInventoryId,
        gemBaseId: gemInventory.gemBase.id,
        gemName: gemInventory.name,
        gemLevel: gemInventory.level,
        gemAttributeType: gemInventory.attributeType,
        gemAttributeValue: gemInventory.attributeValue,
        socketedAt: new Date(),
      });

      // 更新宝石状态为已使用
      await queryRunner.manager.update(
        CharacterGemInventoryEntity,
        { id: gemInventoryId },
        { status: 0 }
      );

      await queryRunner.commitTransaction();

      // 从宝石基础数据中获取属性名称
      const attributeName = await this.getAttributeName(
        gemInventory.attributeType
      );
      const bonusText = `${attributeName}+${gemInventory.attributeValue}`;

      return {
        success: true,
        message: `镶嵌成功.${equipment.name}提升了能力${bonusText}`,
      };
    } catch (error) {
      await queryRunner.rollbackTransaction();
      console.error("宝石镶嵌失败:", error);
      throw error;
    } finally {
      await queryRunner.release();
    }
  }

  /**
   * 镶嵌宝石到装备 (旧版本，保留兼容性)
   */
  async socketGem(
    characterId: number,
    equipmentId: number,
    equipmentType: number,
    socketSlot: number,
    gemInventoryId: number
  ): Promise<{ success: boolean; message: string }> {
    try {
      // 获取宝石信息
      const gemInventory = await this.gemInventoryRepository.findOne({
        where: { id: gemInventoryId, characterId, status: 1 },
        relations: ["gemBase"],
      });

      if (!gemInventory) {
        return {
          success: false,
          message: "宝石不存在或已被使用",
        };
      }

      // 检查装备槽位是否已占用
      const existingSocket = await this.gemSocketRepository.findOne({
        where: {
          characterId,
          equipmentId,
          equipmentType,
          socketSlot,
        },
      });

      if (existingSocket) {
        return {
          success: false,
          message: "该装备槽位已被占用",
        };
      }

      // 检查宝石是否可以镶嵌到该装备类型
      const actualAttributeType = gemInventory.attributeType;

      if (!actualAttributeType) {
        return { success: false, message: "该宝石没有属性信息" };
      }

      // 从gem_attributes表获取实际属性的装备槽位
      const gemAttributeResults = await this.dataSource.query(
        `SELECT equipment_slots FROM gem_attributes WHERE id = ?`,
        [actualAttributeType]
      );

      if (gemAttributeResults.length === 0) {
        return { success: false, message: "该宝石不能镶嵌到任何装备上" };
      }

      const gemAttribute = gemAttributeResults[0];
      const equipmentSlots = gemAttribute.equipment_slots;

      if (!equipmentSlots || equipmentSlots.length === 0) {
        return { success: false, message: "该宝石不能镶嵌到任何装备上" };
      }

      // 解析装备槽位字符串为数组
      const equipmentTypes = equipmentSlots
        .split(",")
        .map((slot: string) => parseInt(slot.trim()));

      if (!equipmentTypes.includes(equipmentType)) {
        return {
          success: false,
          message: "该宝石不能镶嵌到此类装备上",
        };
      }

      // 镶嵌宝石
      await this.gemSocketRepository.save({
        characterId,
        equipmentId,
        equipmentType,
        socketSlot,
        gemInventoryId,
        gemBaseId: gemInventory.gemBaseId,
        gemName: gemInventory.name,
        gemLevel: gemInventory.level,
        gemAttributeType: gemInventory.attributeType,
        gemAttributeValue: gemInventory.attributeValue,
        socketedAt: new Date(),
      });

      // 更新宝石状态为已使用
      await this.gemInventoryRepository.update(
        { id: gemInventoryId },
        { status: 0, updated_at: new Date() }
      );

      return {
        success: true,
        message: `成功将${gemInventory.name}镶嵌到装备上`,
      };
    } catch (error) {
      console.error("镶嵌宝石失败:", error);
      throw error;
    }
  }

  /**
   * 卸下装备上的宝石
   */
  async unsocketGem(
    characterId: number,
    equipmentId: number,
    equipmentType: number,
    socketSlot: number
  ): Promise<{ success: boolean; message: string }> {
    try {
      // 获取镶嵌信息
      const socket = await this.gemSocketRepository.findOne({
        where: {
          characterId,
          equipmentId,
          equipmentType,
          socketSlot,
        },
      });

      if (!socket) {
        return {
          success: false,
          message: "该槽位没有宝石",
        };
      }

      // 恢复宝石到背包
      await this.gemInventoryRepository.update(
        { id: socket.gemInventoryId },
        { status: 1, updated_at: new Date() }
      );

      // 删除镶嵌记录
      await this.gemSocketRepository.delete({ id: socket.id });

      return {
        success: true,
        message: `成功卸下${socket.gemName}`,
      };
    } catch (error) {
      console.error("卸下宝石失败:", error);
      throw error;
    }
  }

  /**
   * 获取装备的宝石镶嵌信息
   */
  async getEquipmentGems(
    characterId: number,
    equipmentId: number,
    equipmentType: number
  ) {
    try {
      const sockets = await this.gemSocketRepository.find({
        where: {
          characterId,
          equipmentId,
          equipmentType,
        },
        order: { socketSlot: "ASC" },
      });

      return sockets.map((socket) => ({
        slot: socket.socketSlot,
        gemName: socket.gemName,
        gemLevel: socket.gemLevel,
        gemAttributeType: socket.gemAttributeType,
        gemAttributeValue: socket.gemAttributeValue,
        socketedAt: socket.socketedAt,
      }));
    } catch (error) {
      console.error("获取装备宝石信息失败:", error);
      throw error;
    }
  }

  /**
   * 生成固定区间值
   */
  private generateFixedIntervalValue(
    attributeType: number,
    minValue: number,
    maxValue: number,
    level: number
  ): number {
    // 根据属性类型确定最大加成值和区间大小
    const attributeConfig: {
      [key: number]: { max: number; interval: number };
    } = {
      1: { max: 750, interval: 50 }, // 攻击力: 50, 100, 150, 200, 250, 300, 350, 400, 450, 500, 550, 600, 650, 700, 750
      2: { max: 750, interval: 50 }, // 防御力: 50, 100, 150, 200, 250, 300, 350, 400, 450, 500, 550, 600, 650, 700, 750
      3: { max: 1500, interval: 100 }, // 生命值: 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000, 1100, 1200, 1300, 1400, 1500
      4: { max: 1500, interval: 100 }, // 魔法值: 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000, 1100, 1200, 1300, 1400, 1500
      5: { max: 750, interval: 50 }, // 魔法攻击: 50, 100, 150, 200, 250, 300, 350, 400, 450, 500, 550, 600, 650, 700, 750
      6: { max: 750, interval: 50 }, // 魔法防御: 50, 100, 150, 200, 250, 300, 350, 400, 450, 500, 550, 600, 650, 700, 750
      7: { max: 15, interval: 1 }, // 暴击率: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
      8: { max: 15, interval: 1 }, // 暴击伤害: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
      9: { max: 15, interval: 1 }, // 命中率: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
      10: { max: 15, interval: 1 }, // 闪避率: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
      11: { max: 15, interval: 1 }, // 格挡率: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
      12: { max: 15, interval: 1 }, // 反击率: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
      13: { max: 15, interval: 1 }, // 经验加成: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
      14: { max: 15, interval: 1 }, // 金币加成: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
      15: { max: 15, interval: 1 }, // 移动速度: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
      16: { max: 15, interval: 1 }, // 体质: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
      17: { max: 15, interval: 1 }, // 智力: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
      18: { max: 15, interval: 1 }, // 力量: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
      19: { max: 15, interval: 1 }, // 敏捷: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
      20: { max: 1500, interval: 100 }, // 气血: 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000, 1100, 1200, 1300, 1400, 1500
      21: { max: 1500, interval: 100 }, // 精力: 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000, 1100, 1200, 1300, 1400, 1500
      22: { max: 15, interval: 1 }, // 致命率: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
      23: { max: 15, interval: 1 }, // 反震率: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
      24: { max: 15, interval: 1 }, // 躲避率: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
      25: { max: 15, interval: 1 }, // 暴击力: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
      26: { max: 15, interval: 1 }, // 穿透率: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
      27: { max: 12, interval: 1 }, // 法爆率: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12
      28: { max: 15, interval: 1 }, // 爆伤力: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
      29: { max: 10, interval: 1 }, // 法伤力: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
      30: { max: 10, interval: 1 }, // 法穿率: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
      31: { max: 3, interval: 1 }, // 连击数: 1, 2, 3
      32: { max: 15, interval: 1 }, // 连击率: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
      33: { max: 15, interval: 1 }, // 抗物理: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
      34: { max: 15, interval: 1 }, // 抗围困: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
      35: { max: 15, interval: 1 }, // 抗扰乱: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
      36: { max: 15, interval: 1 }, // 抗封锁: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
      37: { max: 15, interval: 1 }, // 抗风沙: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
      38: { max: 15, interval: 1 }, // 抗妖火: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
      39: { max: 15, interval: 1 }, // 抗落雷: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
      40: { max: 15, interval: 1 }, // 抗毒术: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
    };

    const config = attributeConfig[attributeType] || { max: 15, interval: 1 };
    const maxAttributeValue = config.max;
    const intervalSize = config.interval;

    // 计算等级对应的属性值区间
    const levelRatio = level / 20; // 假设最大等级为20
    const targetValue = Math.floor(maxAttributeValue * levelRatio);

    // 计算最接近的区间值
    const intervalIndex = Math.floor(targetValue / intervalSize);
    const intervalValue = Math.min(
      (intervalIndex + 1) * intervalSize,
      maxAttributeValue
    );

    // 确保在配置的范围内
    return Math.min(Math.max(intervalValue, minValue), maxValue);
  }

  /**
   * 根据权重选择属性
   */
  private selectAttributeByWeight(possibleAttributes: any[]): any {
    // 计算总权重
    const totalWeight = possibleAttributes.reduce(
      (sum, attr) => sum + attr.weight,
      0
    );

    // 生成随机数
    const random = Math.random() * totalWeight;

    // 根据权重选择属性
    let currentWeight = 0;
    for (const attr of possibleAttributes) {
      currentWeight += attr.weight;
      if (random <= currentWeight) {
        return attr;
      }
    }

    // 如果没找到，返回第一个属性
    return possibleAttributes[0];
  }

  /**
   * 获取宝石的可能属性列表
   */
  async getGemPossibleAttributes(gemBaseId: number): Promise<any[]> {
    try {
      // 使用原生SQL查询gem_attributes表
      const results = await this.dataSource.query(
        `
        SELECT 
          ga.id,
          ga.gem_id,
          ga.attribute_name,
          ga.equipment_slots,
          ga.max_value
        FROM gem_attributes ga
        WHERE ga.gem_id = ?
      `,
        [gemBaseId]
      );

      return results.map((row: any) => ({
        type: row.id,
        name: row.attribute_name,
        min: 1, // 最小值为1
        max: row.max_value,
        weight: 100, // 默认权重为100
        equipmentSlots: row.equipment_slots,
      }));
    } catch (error) {
      this.logger.error("获取宝石可能属性失败:", error);
      return [];
    }
  }

  /**
   * 根据属性类型获取属性名称
   */
  async getAttributeName(attributeType: number): Promise<string> {
    try {
      // 从gem_attributes表查询属性名称
      const results = await this.dataSource.query(
        `SELECT attribute_name FROM gem_attributes WHERE id = ?`,
        [attributeType]
      );

      if (results.length > 0) {
        return results[0].attribute_name;
      }

      return "未知属性";
    } catch (error) {
      console.error("获取属性名称失败:", error);
      return "未知属性";
    }
  }

  /**
   * 计算装备总属性加成
   */
  async calculateEquipmentAttributes(
    characterId: number,
    equipmentId: number,
    equipmentType: number
  ): Promise<any> {
    try {
      const sockets = await this.gemSocketRepository.find({
        where: {
          characterId,
          equipmentId,
          equipmentType,
        },
      });

      const totalAttributes: { [key: string]: number } = {};

      sockets.forEach((socket) => {
        // 累加属性值
        if (socket.gemAttributeType) {
          totalAttributes[socket.gemAttributeType] =
            (totalAttributes[socket.gemAttributeType] || 0) +
            socket.gemAttributeValue;
        }
      });

      return totalAttributes;
    } catch (error) {
      console.error("计算装备属性失败:", error);
      throw error;
    }
  }

  /**
   * 获取所有宝石基础信息
   */
  async getAllGemBases() {
    try {
      return await this.gemBaseRepository.find({
        order: { id: "ASC" },
      });
    } catch (error) {
      console.error("获取宝石基础信息失败:", error);
      throw error;
    }
  }

  /**
   * 获取开矿配置
   */
  async getMiningConfigs() {
    try {
      return await this.gemMiningRepository.find({
        where: { status: 1 },
        order: { type: "ASC" },
      });
    } catch (error) {
      console.error("获取开矿配置失败:", error);
      throw error;
    }
  }

  /**
   * 获取宝石详情 (1064)
   */
  async getGemDetail(characterId: number, gemId: number) {
    try {
      // 查找宝石背包中的宝石
      const gem = await this.gemInventoryRepository.findOne({
        where: {
          id: gemId,
          characterId,
          status: 1,
        },
        relations: ["gemBase"],
      });

      if (!gem) {
        return {
          success: false,
          message: "宝石不存在或已丢弃",
        };
      }

      // 构建宝石详情信息
      const gemDetail = {
        id: gem.id,
        name: gem.name,
        lvl: gem.level,
        type: gem.gemBase?.id || 1,
        describe: await this.buildGemDescription(gem.gemBase),
        effect: await this.buildGemEffect(gem),
        value: gem.attributeValue || 0,
        lock: false, // 宝石默认不锁定
      };

      return {
        success: true,
        data: gemDetail,
      };
    } catch (error) {
      console.error("获取宝石详情失败:", error);
      throw error;
    }
  }

  /**
   * 丢弃宝石 (1091)
   */
  async discardGem(
    characterId: number,
    gemId: number
  ): Promise<{ success: boolean; message: string }> {
    try {
      // 查找宝石背包中的宝石
      const gem = await this.gemInventoryRepository.findOne({
        where: {
          id: gemId,
          characterId,
          status: 1,
        },
        relations: ["gemBase"],
      });

      if (!gem) {
        return {
          success: false,
          message: "宝石不存在或已丢弃",
        };
      }

      // 检查宝石是否镶嵌在装备上
      const socket = await this.gemSocketRepository.findOne({
        where: {
          gemInventoryId: gemId,
        },
      });

      if (socket) {
        return {
          success: false,
          message: "宝石已镶嵌在装备上，请先卸下再丢弃",
        };
      }

      // 标记宝石为已丢弃
      await this.gemInventoryRepository.update(gemId, {
        status: -1,
        updated_at: new Date(),
      });

      return {
        success: true,
        message: `您丢弃了一个${gem.name}`,
      };
    } catch (error) {
      console.error("丢弃宝石失败:", error);
      throw error;
    }
  }

  /**
   * 构建宝石描述
   */
  private async buildGemDescription(gemBase: any): Promise<string> {
    // 使用宝石属性ID数组获取装备槽位信息
    if (
      gemBase?.attributeId &&
      Array.isArray(gemBase.attributeId) &&
      gemBase.attributeId.length > 0
    ) {
      const gemAttributes = await this.gemAttributeRepository.findByIds(
        gemBase.attributeId
      );

      if (gemAttributes && gemAttributes.length > 0) {
        const slotNames: { [key: number]: string } = {
          1: "头盔",
          2: "武器",
          3: "铠甲",
          4: "项链",
          5: "护腕",
          6: "鞋子",
        };

        // 收集所有可能的装备槽位
        const allSlots = new Set<number>();
        gemAttributes.forEach((attr) => {
          if (attr.equipmentSlots && Array.isArray(attr.equipmentSlots)) {
            attr.equipmentSlots.forEach((slot) => allSlots.add(slot));
          }
        });

        const slots = Array.from(allSlots)
          .map((slot: number) => slotNames[slot] || `槽位${slot}`)
          .join(",");
        return `可镶嵌于${slots}`;
      }
    }

    // 如果没有属性表数据，返回默认描述
    return "可镶嵌于装备";
  }

  /**
   * 构建宝石效果描述
   */
  private async buildGemEffect(gem: any): Promise<string> {
    if (!gem || !gem.attributeValue) {
      return "无效果";
    }

    // 使用attributeType从gem_attribute表获取属性名称
    if (gem.attributeType) {
      try {
        const attribute = await this.gemAttributeRepository.findOne({
          where: { id: gem.attributeType },
        });
        if (attribute) {
          return `${attribute.attributeName}+${gem.attributeValue}`;
        }
      } catch (error) {
        console.error("获取宝石属性名称失败:", error);
      }
    }

    // 如果没有属性表数据，返回默认描述
    return `属性+${gem.attributeValue}`;
  }

  /**
   * 洗孔功能 - 删除指定装备槽位的宝石镶嵌数据，同时删除玩家宝石表中的对应宝石
   * @param characterId 角色ID
   * @param equipmentId 装备ID
   * @param socketSlot 槽位位置 (1, 2, 3)
   * @returns 操作结果
   */
  async washSocket(
    characterId: number,
    equipmentId: number,
    socketSlot: number
  ): Promise<{ success: boolean; message: string; cost?: number }> {
    const queryRunner = this.dataSource.createQueryRunner();
    await queryRunner.connect();
    await queryRunner.startTransaction();

    try {
      // 1. 查找指定装备槽位的宝石镶嵌记录
      const socketRecord = await queryRunner.manager.findOne(
        EquipmentGemSocketEntity,
        {
          where: {
            characterId,
            equipmentId,
            socketSlot,
          },
        }
      );

      if (!socketRecord) {
        await queryRunner.rollbackTransaction();
        return {
          success: false,
          message: "该槽位没有镶嵌宝石",
        };
      }

      // 2. 获取宝石信息用于日志记录
      const gemInventory = await queryRunner.manager.findOne(
        CharacterGemInventoryEntity,
        {
          where: { id: socketRecord.gemInventoryId },
        }
      );

      if (!gemInventory) {
        await queryRunner.rollbackTransaction();
        return {
          success: false,
          message: "宝石信息不存在",
        };
      }

      // 3. 删除装备宝石镶嵌记录
      await queryRunner.manager.delete(EquipmentGemSocketEntity, {
        id: socketRecord.id,
      });

      // 4. 删除玩家宝石表中的对应宝石
      await queryRunner.manager.delete(CharacterGemInventoryEntity, {
        id: socketRecord.gemInventoryId,
      });

      // 5. 计算洗孔费用（根据宝石等级计算）
      const washCost = this.calculateWashCost(gemInventory.level);

      // 6. 检查并扣除银币
      const characterResources = await queryRunner.manager.findOne(
        CharacterResourcesEntity,
        {
          where: { characterId },
        }
      );

      if (!characterResources) {
        await queryRunner.rollbackTransaction();
        return {
          success: false,
          message: "角色资源信息不存在",
        };
      }

      // 检查银币是否足够
      if (characterResources.silver < washCost) {
        await queryRunner.rollbackTransaction();
        return {
          success: false,
          message: `银币不足，需要 ${washCost} 银币，当前只有 ${characterResources.silver} 银币`,
        };
      }

      // 扣除银币
      characterResources.silver -= washCost;
      await queryRunner.manager.save(characterResources);

      await queryRunner.commitTransaction();

      this.logger.log(
        `✅ 洗孔成功: 角色${characterId} 装备${equipmentId} 槽位${socketSlot} 宝石${gemInventory.name} 费用${washCost}银币 剩余银币${characterResources.silver}`
      );

      return {
        success: true,
        message: `洗孔完成,花费 ${washCost} 银`,
        cost: washCost,
      };
    } catch (error: any) {
      await queryRunner.rollbackTransaction();
      this.logger.error("洗孔失败:", error);
      return {
        success: false,
        message: error?.message || "洗孔失败",
      };
    } finally {
      await queryRunner.release();
    }
  }

  /**
   * 计算洗孔费用
   * @param gemLevel 宝石等级
   * @returns 洗孔费用（银币）
   */
  private calculateWashCost(gemLevel: number): number {
    // 根据宝石等级计算洗孔费用
    // 1级宝石: 100银币, 2级: 200银币, 以此类推
    return gemLevel * 100;
  }

  private computeAttributeValue(level: number, maxValue: number): number {
    const clampedLevel = Math.max(1, Math.min(10, Math.floor(level)));
    const rand = Math.floor(Math.random() * 3); // 0..2
    const perStep = maxValue / 15;
    const raw = (clampedLevel + rand) * perStep;
    return Math.floor(raw);
  }
}
